package org.yzbdl.lanius.orchestrate.system.controller;


import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.yzbdl.lanius.orchestrate.common.annotation.auth.CheckPermission;
import org.yzbdl.lanius.orchestrate.common.annotation.log.OprId;
import org.yzbdl.lanius.orchestrate.common.annotation.log.OprLog;
import org.yzbdl.lanius.orchestrate.common.constant.UserOprEventConstant;
import org.yzbdl.lanius.orchestrate.common.dto.system.*;
import org.yzbdl.lanius.orchestrate.common.entity.system.UserEntity;
import org.yzbdl.lanius.orchestrate.common.exception.runtime.InvalidCodeException;
import org.yzbdl.lanius.orchestrate.common.result.ResultObj;
import org.yzbdl.lanius.orchestrate.common.utils.MessageUtil;
import org.yzbdl.lanius.orchestrate.common.vo.system.UserTokenVo;
import org.yzbdl.lanius.orchestrate.common.vo.system.UserVo;
import org.yzbdl.lanius.orchestrate.serv.service.system.OrgService;
import org.yzbdl.lanius.orchestrate.serv.service.system.UserAuthService;
import org.yzbdl.lanius.orchestrate.serv.service.system.UserService;
import org.yzbdl.lanius.orchestrate.serv.utils.CurrentUserUtil;
import org.yzbdl.lanius.orchestrate.serv.utils.VerifyCodeUtil;

import java.util.List;

/**
 * @author chenjunhao@yzbdl.ac.cn
 * @date 2022/3/24
 */
@Api(tags = "用户相关接口")
@RestController
@RequestMapping("/user")
@Validated
public class UserController {

    @Autowired
    UserService userService;
    @Autowired
    UserAuthService userAuthService;
    @Autowired
    OrgService orgService;
    @Value("${verify-code.skip}")
    boolean verifyCodeSkip;

    @OprLog(value = UserOprEventConstant.SYSTEM_USER_LOGIN, msg = "用户${userName}执行登录操作")
    @ApiOperation(value = "用户登录", notes = "")
    @RequestMapping(value = "login", method = RequestMethod.POST)
    public ResultObj<?> login(@RequestBody @Validated UserLoginParamDto userLoginParamDto, @RequestParam String key) {
        if (!verifyCodeSkip && !VerifyCodeUtil.verify(key, userLoginParamDto.getCode())) {
            throw new InvalidCodeException(MessageUtil.get("system.user.login.valid_code_fail"));
        }
        return ResultObj.success(userAuthService.login(userLoginParamDto.getUserName(), userLoginParamDto.getPassword()));
    }

    @ApiOperation(value = "刷新token", notes = "")
    @RequestMapping(value = "/refresh", method = RequestMethod.POST)
    public ResultObj<UserTokenVo> refresh(@RequestBody @Validated TokenRefreshDto tokenRefreshDto) {
        return ResultObj.success(userAuthService.refresh(tokenRefreshDto.getRefreshToken()));
    }

    @OprLog(value = UserOprEventConstant.SYSTEM_USER_LOGIN, msg = "新增用户${userName}")
    @ApiOperation(value = "新增成员", notes = "")
    @RequestMapping(value = "", method = RequestMethod.POST)
    public ResultObj<?> insertUser(@RequestBody @Validated MemberInsertParamDTO memberInsertParamDTO){
        userService.addOrgMember(memberInsertParamDTO);
        return ResultObj.success(false);
    }

    @OprLog(value = UserOprEventConstant.SYSTEM_USER_EDIT, msg = "更改了用户${userName}的所属角色")
    @CheckPermission("system::user::edit")
    @ApiOperation(value = "保存用户角色", notes = "")
    @RequestMapping(value = "/{userId}/roles", method = RequestMethod.POST)
    public ResultObj<Integer> saveUserRole(
            @RequestBody List<Long> roleIds,
            @PathVariable(value = "userId") @OprId(server = UserService.class) Long userId
    ) {
        return ResultObj.success(userService.saveUserRoles(roleIds, userId));
    }

    @CheckPermission("system::user::query")
    @ApiOperation(value = "根据id获取用户", notes = "")
    @RequestMapping(value = "/{userId}", method = RequestMethod.GET)
    public ResultObj<UserEntity> getById(@PathVariable(value = "userId") Long userId) {
        return ResultObj.success(userService.getById(userId));
    }

    @CheckPermission("system::user::query")
    @ApiOperation(value = "分页查询用户", notes = "")
    @RequestMapping(value = "/query", method = RequestMethod.POST)
    public ResultObj<Page<UserVo>> query(
            @RequestParam(defaultValue = "20") int size,
            @RequestParam(defaultValue = "1") int page,
            @RequestBody @Validated UserListDTO userListDto
    ) {
        return ResultObj.success(userService.listUserPage(userListDto, new Page<>(page, size)));
    }

    @CheckPermission("system::user::delete")
    @ApiOperation(value = "将用户移除当前组织", notes = "")
    @RequestMapping(value = "/{userId}", method = RequestMethod.DELETE)
    public ResultObj<Boolean> removeById(@PathVariable("userId") @OprId(server = UserService.class) Long userId) {
        return ResultObj.success(userService.removeFromOrg(userId, CurrentUserUtil.getCurrentUserOrgId()));
    }

    @CheckPermission("system::user::delete")
    @ApiOperation(value = "获取不在当前组织的用户", notes = "")
    @RequestMapping(value = "/notInOrg", method = RequestMethod.POST)
    public ResultObj<List<SimpleUserVO>> listUsersNotInOrg(@RequestParam(required = false) String likeName) {
        return ResultObj.success(userService.listUsersNotInOrg(CurrentUserUtil.getCurrentUserOrgId(), likeName));
    }

}
